#include "tlv_pack_com.h"
#include "common.h"
#include <string.h>
#include <stdio.h>

/* fixbyme：区分有boot还是没boot模式的设备ID
   有boot：需要从FLASH中读取
   无boot：自定义*/
#ifdef BIN_MODE_OPEN
uint16_t g_DeviceID = 0xFFFF;
#else
uint16_t g_DeviceID = DEVICE_ID;
#endif

/* 参数说明：
   deviceid：设备ID，根据设备属性配置
   tlvpack： tlv结构体地址
   sendbuf： 发送指令缓存地址
   返回：sendbuf数据长度*/
uint16_t hal_pack(uint16_t deviceid, struct TLVPacket *tlvpack, uint8_t *sendbuf)
{
    if (tlvpack == NULL || sendbuf == NULL)
    {
        return 0;
    }

    /* 结构体转换*/
    struct MsgBuffferHeadSt *tlvhead = (struct MsgBuffferHeadSt *)sendbuf;

    if (Int8ToInt16BigEnd(tlvpack->length) > (sizeof(struct TLVPacket) - PROTOCOL_TAG_LEN - PROTOCOL_LENGTH_LEN))
    {
        return 0;
    }

    /* CRC地址*/
    uint8_t *pbuff                  = sendbuf + (sizeof(struct MsgBuffferHeadSt)) - (sizeof(tlvpack->value)) + Int8ToInt16BigEnd(tlvpack->length);
    struct MsgBufferTailSt *tlvtail = (struct MsgBufferTailSt *)pbuff;
    /* 帧尾地址*/
    pbuff += sizeof(struct MsgBufferTailSt);
    uint16_t sebdbuflen = pbuff - sendbuf;

    /* 帧头 设备号 TLV结构体拷贝*/
    Int16ToInt8BigEnd(PROTOCOL_HEAD, tlvhead->head);
    Int16ToInt8BigEnd(deviceid, tlvhead->deviceid);
    memcpy(tlvhead->tlvpacket.tag, tlvpack->tag, (PROTOCOL_TAG_LEN + PROTOCOL_LENGTH_LEN + Int8ToInt16BigEnd(tlvpack->length)));
    /* 和校验计算*/
    uint32_t crc = CheckSumCalc(&tlvhead->deviceid[0], (&tlvtail->check[0] - &tlvhead->deviceid[0]));
    /* 和校验 帧尾拷贝*/
    Int32ToInt8BigEnd(crc, tlvtail->check);
    Int16ToInt8BigEnd(PROTOCOL_TAIL, tlvtail->tail);

    return sebdbuflen;
}
/* 参数说明：
   rcvbuf：接收指令缓存地址
   rcvlen： 接收指令缓存数据长度
   tlvpack： tlv结构体地址
   返回：状态 0失败 ，1成功*/
uint8_t hal_unpack(uint8_t *rcvbuf, uint8_t rcvlen, struct TLVPacket *tlvpack)
{
    if (rcvbuf == NULL || tlvpack == NULL)
    {
        return 0;
    }

    struct MsgBuffferHeadSt *tlvhead = (struct MsgBuffferHeadSt *)rcvbuf;
    uint8_t *pcrc                    = rcvbuf + rcvlen - sizeof(struct MsgBufferTailSt);
    struct MsgBufferTailSt *tlvtail  = (struct MsgBufferTailSt *)pcrc;

    if (Int8ToInt16BigEnd(tlvhead->head) != PROTOCOL_HEAD || Int8ToInt16BigEnd(tlvtail->tail) != PROTOCOL_TAIL || tlvhead->tlvpacket.tagmodule != DEVICE_MODULE ||
        Int8ToInt16BigEnd(tlvhead->deviceid) != g_DeviceID || Int8ToInt32BigEnd(tlvtail->check) != CheckSumCalc(rcvbuf + PROTOCOL_HEAD_LEN, (pcrc - rcvbuf - PROTOCOL_HEAD_LEN)))
    {
        return 0;
    }

    memcpy(&tlvpack->tag[0], &tlvhead->tlvpacket.tag[0], (PROTOCOL_TAG_LEN + PROTOCOL_LENGTH_LEN + Int8ToInt16BigEnd(&tlvhead->tlvpacket.length[0])));

    return 1;
}